package com.yue.rabbitmq.config;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    public static final String L4G001 = "4g01";
    public static final String L4G002 = "4g02";
    public static final String L4G003 = "4g03";
    public static final String L4G004 = "4g04";
    public static final String L4G005 = "4g05";
    public static final String L4G006 = "4g06";
    public static final String EXCHANGE_L4_MAIN = "l4";
    @Bean
    public Queue l4G001() {
        return new Queue(L4G001, true);
    }
    @Bean
    public Queue l4G002() {
        return new Queue(L4G002, true);
    }
    @Bean
    public Queue l4G003() {
        return new Queue(L4G003, true);
    }
    @Bean
    public Queue l4G004() {
        return new Queue(L4G004, true);
    }
    @Bean
    public Queue l4G005() {
        return new Queue(L4G005, true);
    }
    @Bean
    public Queue l4G006() {
        return new Queue(L4G006, true);
    }
    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(EXCHANGE_L4_MAIN);
    }
    @Bean
    public Binding bindingL41(Queue l4G001, TopicExchange exchange) {
        return BindingBuilder.bind(l4G001).to(exchange).with("l4.4g01");
    }
    @Bean
    public Binding bindingL42(Queue l4G002, TopicExchange exchange) {
        return BindingBuilder.bind(l4G002).to(exchange).with("l4.4g02");
    }

    @Bean
    public Binding bindingL43(Queue l4G003, TopicExchange exchange) {
        return BindingBuilder.bind(l4G003).to(exchange).with("l4.*");
    }
    @Bean
    public ConnectionFactory connectionFactory(
            @Value("${spring.rabbitmq.host}") String host,
            @Value("${spring.rabbitmq.port}") int port,
            @Value("${spring.rabbitmq.username}") String username,
            @Value("${spring.rabbitmq.password}") String password) {

        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED); // 开启生产者确认模式,是否到达交换机会触发一个函数回调
        connectionFactory.setPublisherReturns(true); //是否路由到queue，开启后会触发一个回调函数
        return connectionFactory;
    }
    @Bean
    public RabbitTemplate rabbitTemplate(org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);

        // 消息发送到Exchange确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                System.out.println(String.format("消息成功到达Exchange，消息ID：%s",correlationData.getId()));
            } else {
                System.out.println(String.format("消息未到达Exchange，原因：%s，消息ID：%s",cause,correlationData.getId()));
                // 这里可以实现重发逻辑
            }
        });
        rabbitTemplate.setMandatory(true);
        // 消息未路由到Queue回调
        rabbitTemplate.setReturnsCallback(returned -> {
            System.out.println(String.format("消息未路由到队列，Exchange: %s, RoutingKey: %s, ReplyCode: %s, ReplyText: %s",
                    returned.getExchange(),
                    returned.getRoutingKey(),
                    returned.getReplyCode(),
                    returned.getReplyText()));
            // 这里可以实现补偿逻辑
        });

        return rabbitTemplate;
    }
}